<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
		<title>React + Redux 待办事项应用2</title>
		<style type="text/css">
			html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-feature-settings: "liga", "kern";
          font-feature-settings: "liga", "kern";
  overflow: hidden;
}

* {
  box-sizing: border-box;
}

input,
button,
ul {
  margin: 0;
  border: 0;
  padding: 0;
  display: inline-block;
  vertical-align: middle;
  white-space: normal;
  background: none;
  outline: none;
}

i {
  line-height: 1;
  vertical-align: middle;
}

html,
body {
  width: 100%;
  height: 100%;
}

body {
  font-family: 'Varela Round', sans-serif;
  color: #2E2E2E;
  font-size: 18px;
  line-height: 1.5;
}

.root {
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
      -ms-flex-pack: center;
          justify-content: center;
  background: #ff9068;
  background: -webkit-linear-gradient(45deg, #fd746c, #ff9068);
  background: linear-gradient(45deg, #fd746c, #ff9068);
  height: 100%;
}

.todo-app {
  min-width: 380px;
  max-width: 50%;
  min-height: 480px;
  max-height: 100%;
  background: #fafafa;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-orient: vertical;
  -webkit-box-direction: normal;
  -webkit-flex-direction: column;
      -ms-flex-direction: column;
          flex-direction: column;
  -webkit-box-align: center;
  -webkit-align-items: center;
      -ms-flex-align: center;
          align-items: center;
  -webkit-box-pack: end;
  -webkit-justify-content: flex-end;
      -ms-flex-pack: end;
          justify-content: flex-end;
  border-radius: 5px;
  box-shadow: 0 0 5px rgba(25, 25, 25, 0.25);
  padding: 3rem;
}

.todo-title {
  margin-bottom: auto;
  margin-top: 0;
  line-height: 1;
}

.todo-list {
  font-size: 100%;
  list-style: none;
  width: 100%;
  overflow-x: hidden;
  margin-top: 2rem;
}

.todo {
  line-height: 1.5;
  position: relative;
  padding: 0 2.5rem 0 .75rem;
  -webkit-transition: -webkit-transform 0.5s cubic-bezier(0.55, 0, 0.1, 1);
  transition: -webkit-transform 0.5s cubic-bezier(0.55, 0, 0.1, 1);
  transition: transform 0.5s cubic-bezier(0.55, 0, 0.1, 1);
  transition: transform 0.5s cubic-bezier(0.55, 0, 0.1, 1), -webkit-transform 0.5s cubic-bezier(0.55, 0, 0.1, 1);
}
.todo:after {
  font-family: FontAwesome;
  content: "\f00c";
  position: absolute;
  right: .75rem;
  color: #2ecc71;
  opacity: 0;
  -webkit-transform: scale(0);
          transform: scale(0);
  -webkit-transition: opacity, 0.25s cubic-bezier(0.55, 0, 0.1, 1), -webkit-transform;
  transition: opacity, 0.25s cubic-bezier(0.55, 0, 0.1, 1), -webkit-transform;
  transition: transform, opacity, 0.25s cubic-bezier(0.55, 0, 0.1, 1);
  transition: transform, opacity, 0.25s cubic-bezier(0.55, 0, 0.1, 1), -webkit-transform;
}
.todo + .todo {
  margin-top: 1rem;
  padding-top: 1rem;
}
.todo + .todo:before {
  content: '';
  background: #e8ebed;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  border-radius: 2px;
}
.todo__content {
  position: relative;
  opacity: 1;
  text-transform: capitalize;
  cursor: pointer;
  -webkit-transition: opacity 0.25s ease-out;
  transition: opacity 0.25s ease-out;
}
.todo__content:after {
  content: '';
  position: absolute;
  display: block;
  width: calc( 100% + .5em );
  left: -.25em;
  height: 2px;
  top: 50%;
  border-radius: 1px;
  background: #2E2E2E;
  -webkit-transform-origin: center right;
          transform-origin: center right;
  -webkit-transform: scaleX(0);
          transform: scaleX(0);
  -webkit-transition: -webkit-transform 0.5s cubic-bezier(0.55, 0, 0.1, 1);
  transition: -webkit-transform 0.5s cubic-bezier(0.55, 0, 0.1, 1);
  transition: transform 0.5s cubic-bezier(0.55, 0, 0.1, 1);
  transition: transform 0.5s cubic-bezier(0.55, 0, 0.1, 1), -webkit-transform 0.5s cubic-bezier(0.55, 0, 0.1, 1);
}
.todo.todo--completed:after {
  opacity: 1;
  -webkit-transform: scale(1);
          transform: scale(1);
}
.todo.todo--completed .todo__content {
  opacity: 0.5;
}
.todo.todo--completed .todo__content:after {
  -webkit-transform: scaleX(1);
          transform: scaleX(1);
  -webkit-transform-origin: center left;
          transform-origin: center left;
}

.todo-enter {
  opacity: 0;
  padding-top: 0;
  margin-top: 0;
  max-height: 0;
  -webkit-transform: translateX(-100%);
          transform: translateX(-100%);
  -webkit-transition: opacity 500ms ease-out, max-height 500ms ease-out, padding 500ms ease-out, margin 500ms ease-out, -webkit-transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44);
  transition: opacity 500ms ease-out, max-height 500ms ease-out, padding 500ms ease-out, margin 500ms ease-out, -webkit-transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44);
  transition: opacity 500ms ease-out, transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44), max-height 500ms ease-out, padding 500ms ease-out, margin 500ms ease-out;
  transition: opacity 500ms ease-out, transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44), max-height 500ms ease-out, padding 500ms ease-out, margin 500ms ease-out, -webkit-transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44);
}

.todo-enter.todo-enter-active {
  opacity: 1;
  max-height: 100px;
  -webkit-transform: translateX(0);
          transform: translateX(0);
}

.todo-leave {
  opacity: 1;
  -webkit-transform: translateX(0);
          transform: translateX(0);
  -webkit-transition: opacity 500ms ease-out, max-height 500ms ease-out, padding 500ms ease-out, margin 500ms ease-out, -webkit-transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44);
  transition: opacity 500ms ease-out, max-height 500ms ease-out, padding 500ms ease-out, margin 500ms ease-out, -webkit-transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44);
  transition: opacity 500ms ease-out, transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44), max-height 500ms ease-out, padding 500ms ease-out, margin 500ms ease-out;
  transition: opacity 500ms ease-out, transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44), max-height 500ms ease-out, padding 500ms ease-out, margin 500ms ease-out, -webkit-transform 750ms cubic-bezier(0.87, -0.41, 0.19, 1.44);
}

.todo-leave.todo-leave-active {
  opacity: 0;
  padding-top: 0;
  margin-top: 0;
  max-height: 0;
  -webkit-transform: translateX(100%);
          transform: translateX(100%);
}

.add-todo {
  width: 100%;
  position: relative;
  margin: 2rem 0;
}
.add-todo__btn {
  text-align: center;
  color: #fafafa;
  line-height: 1;
  position: absolute;
  font-size: 150%;
  right: 0;
  top: 50%;
  border-radius: 50%;
  width: 55px;
  height: 55px;
  background: #2ecc71;
  opacity: 0;
  -webkit-transform: translate(0, -50%) scale(0) rotate(180deg);
          transform: translate(0, -50%) scale(0) rotate(180deg);
  -webkit-transition: opacity, 0.5s cubic-bezier(0.87, -0.41, 0.19, 1.44), -webkit-transform;
  transition: opacity, 0.5s cubic-bezier(0.87, -0.41, 0.19, 1.44), -webkit-transform;
  transition: transform, opacity, 0.5s cubic-bezier(0.87, -0.41, 0.19, 1.44);
  transition: transform, opacity, 0.5s cubic-bezier(0.87, -0.41, 0.19, 1.44), -webkit-transform;
}
.add-todo__btn:focus {
  opacity: 1;
  -webkit-transform: translate(50%, -50%) scale(1.1) rotate(0deg);
          transform: translate(50%, -50%) scale(1.1) rotate(0deg);
}
.add-todo__btn:active {
  opacity: 1;
  -webkit-transition: opacity, 0.1s cubic-bezier(0.87, -0.41, 0.19, 1.44), -webkit-transform;
  transition: opacity, 0.1s cubic-bezier(0.87, -0.41, 0.19, 1.44), -webkit-transform;
  transition: transform, opacity, 0.1s cubic-bezier(0.87, -0.41, 0.19, 1.44);
  transition: transform, opacity, 0.1s cubic-bezier(0.87, -0.41, 0.19, 1.44), -webkit-transform;
  -webkit-transform: translate(50%, -50%) scale(0.95) rotate(0deg);
          transform: translate(50%, -50%) scale(0.95) rotate(0deg);
}
.add-todo__input {
  width: 100%;
  border-radius: 5px;
  padding: .5rem 1rem;
  background: #e8ebed;
  margin: 0;
  outline: 0;
  border: 2px solid #e8ebed;
  -webkit-transition: background .25s ease-out;
  transition: background .25s ease-out;
}
.add-todo__input:focus {
  background: none;
}
.add-todo__input:focus + .add-todo__btn {
  opacity: 1;
  -webkit-transform: translate(50%, -50%) scale(1) rotate(0deg);
          transform: translate(50%, -50%) scale(1) rotate(0deg);
}

.filters .filter__link {
  margin: 0 1em;
  font-size: 150%;
}
.filters .fa-list-ul {
  color: #3498db;
}
.filters .fa-times {
  color: #e74c3c;
}
.filters .fa-check {
  color: #2ecc71;
}
.filters .filter__link i {
  -webkit-transition: -webkit-transform 0.5s cubic-bezier(0.87, -0.41, 0.19, 1.44);
  transition: -webkit-transform 0.5s cubic-bezier(0.87, -0.41, 0.19, 1.44);
  transition: transform 0.5s cubic-bezier(0.87, -0.41, 0.19, 1.44);
  transition: transform 0.5s cubic-bezier(0.87, -0.41, 0.19, 1.44), -webkit-transform 0.5s cubic-bezier(0.87, -0.41, 0.19, 1.44);
}
.filters .filter__link i:hover {
  -webkit-transform: scale(1.1);
          transform: scale(1.1);
}
.filters .filter__link i:active {
  -webkit-transform: scale(0.95);
          transform: scale(0.95);
}

		</style>
	</head>
	<body>
		<link href="//cdn.bootcss.com/font-awesome/4.4.0/css/font-awesome.min.css" rel="stylesheet" media="screen">
<link href='https://fonts.googleapis.com/css?family=Varela+Round' rel='stylesheet' type='text/css'>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.5.2/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/expect/1.20.2/expect.min.js"></script>
<script src="https://npmcdn.com/react@15.1.0/dist/react-with-addons.min.js"></script>
<script src="https://npmcdn.com/react-dom@15.1.0/dist/react-dom.min.js"></script>
<div id="root" class="root"></div>


<script type="text/javascript">
	'use strict';

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var todos = function todos() {
	var state = arguments.length <= 0 || arguments[0] === undefined ? [] : arguments[0];
	var action = arguments[1];

	switch (action.type) {
		case 'ADD_TODO':
			return [].concat(state, [{
				id: action.id,
				text: action.text,
				completed: false
			}]);
		case 'TOGGLE_TODO':
			return state.map(function (todo) {
				if (todo.id !== action.id) {
					return todo;
				}
				return _extends({}, todo, {
					completed: !todo.completed
				});
			});
		default:
			return state;
	}
};

var visibilityFilter = function visibilityFilter() {
	var state = arguments.length <= 0 || arguments[0] === undefined ? 'SHOW_ALL' : arguments[0];
	var action = arguments[1];

	switch (action.type) {
		case 'SET_VISIBILITY_FILTER':
			return action.filter;
		default:
			return state;
	}
};

var _Redux = Redux;
var combineReducers = _Redux.combineReducers;

var todoApp = combineReducers({
	todos: todos,
	visibilityFilter: visibilityFilter
});

var _Redux2 = Redux;
var createStore = _Redux2.createStore;

var store = createStore(todoApp);
var _React = React;
var Component = _React.Component;

var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;

var Todo = function Todo(_ref) {
	var onClick = _ref.onClick;
	var completed = _ref.completed;
	var text = _ref.text;
	return React.createElement(
		'li',
		{
			className: completed ? 'todo todo--completed' : 'todo',
			onClick: onClick
		},
		React.createElement(
			'span',
			{ className: 'todo__content' },
			text
		)
	);
};

var TodoList = function TodoList(_ref2) {
	var todos = _ref2.todos;
	var onTodoClick = _ref2.onTodoClick;

	return React.createElement(
		ReactCSSTransitionGroup,
		{
			className: 'todo-list',
			component: 'ul',
			transitionName: 'todo',
			transitionEnterTimeout: 750,
			transitionLeaveTimeout: 750
		},
		todos.map(function (todo) {
			return React.createElement(Todo, _extends({
				key: todo.id
			}, todo, {
				onClick: function onClick() {
					return onTodoClick(todo.id);
				}
			}));
		})
	);
};

var AddTodo = function AddTodo(_ref3) {
	var onAddClick = _ref3.onAddClick;

	var input = undefined;
	return React.createElement(
		'div',
		{ className: 'add-todo' },
		React.createElement('input', {
			className: 'add-todo__input',
			ref: function ref(node) {
				input = node;
			} }),
		React.createElement(
			'button',
			{
				className: 'add-todo__btn',
				onClick: function onClick() {
					input.value ? onAddClick(input.value) : false;
					input.value = '';
				} },
			React.createElement('i', { className: 'fa fa-plus' })
		)
	);
};

var FilterLink = function FilterLink(_ref4) {
	var filter = _ref4.filter;
	var currentFilter = _ref4.currentFilter;
	var children = _ref4.children;
	var _onClick = _ref4.onClick;

	return React.createElement(
		'a',
		{
			className: 'filter__link',
			href: '#',
			onClick: function onClick(e) {
				e.preventDefault();
				_onClick(filter);
			}
		},
		children
	);
};

var Footer = function Footer(_ref5) {
	var visibilityFilter = _ref5.visibilityFilter;
	var onFilterClick = _ref5.onFilterClick;
	return React.createElement(
		'div',
		{ className: 'filters' },
		React.createElement(
			FilterLink,
			{
				filter: 'SHOW_ALL',
				currentFilter: visibilityFilter,
				onClick: onFilterClick
			},
			React.createElement('i', { className: 'fa fa-list-ul' })
		),
		React.createElement(
			FilterLink,
			{
				filter: 'SHOW_ACTIVE',
				currentFilter: visibilityFilter,
				onClick: onFilterClick
			},
			React.createElement('i', { className: 'fa fa-times' })
		),
		React.createElement(
			FilterLink,
			{
				filter: 'SHOW_COMPLETED',
				currentFilter: visibilityFilter,
				onClick: onFilterClick
			},
			React.createElement('i', { className: 'fa fa-check' })
		)
	);
};

var getVisibleTodos = function getVisibleTodos(todos, filter) {
	switch (filter) {
		case 'SHOW_ALL':
			return todos;
		case 'SHOW_COMPLETED':
			return todos.filter(function (t) {
				return t.completed;
			});
		case 'SHOW_ACTIVE':
			return todos.filter(function (t) {
				return !t.completed;
			});
	}
};

var nextTodoId = 0;
var TodoApp = function TodoApp(_ref6) {
	var todos = _ref6.todos;
	var visibilityFilter = _ref6.visibilityFilter;
	return React.createElement(
		'div',
		{ className: 'todo-app' },
		React.createElement(
			'h1',
			{ className: 'todo-title' },
			'Todos'
		),
		React.createElement(TodoList, {
			todos: getVisibleTodos(todos, visibilityFilter),
			onTodoClick: function onTodoClick(id) {
				return store.dispatch({
					type: 'TOGGLE_TODO',
					id: id
				});
			}
		}),
		React.createElement(AddTodo, {
			onAddClick: function onAddClick(text) {
				return store.dispatch({
					type: 'ADD_TODO',
					id: nextTodoId++,
					text: text
				});
			}
		}),
		React.createElement(Footer, {
			visibilityFilter: visibilityFilter,
			onFilterClick: function onFilterClick(filter) {
				return store.dispatch({
					type: 'SET_VISIBILITY_FILTER',
					filter: filter
				});
			}
		})
	);
};

var render = function render() {
	ReactDOM.render(React.createElement(TodoApp, store.getState()), document.getElementById('root'));
};

store.subscribe(render);
render();

/*
 * Tests
 */

// const testAddTodo = () => {
// 	const stateBefore = [];
// 	const action = {
// 		type: 'ADD_TODO',
// 		id: 0,
// 		text: 'Learn Redux'
// 	};
// 	const stateAfter = [
// 		{
// 			id: 0,
// 			text: 'Learn Redux',
// 			completed: false
// 		}
// 	];
// 	expect(
// 		todos(stateBefore, action)
// 	).toEqual(stateAfter);
// };

// const testToggleTodo = () => {
// 	const stateBefore = [
// 		{
// 			id: 0,
// 			text: 'Learn Redux',
// 			completed: false
// 		},
// 		{
// 			id: 1,
// 			text: 'Profit!',
// 			completed: false
// 		}
// 	];
// 	const action = {
// 		type: 'TOGGLE_TODO',
// 		id: 1
// 	};
// 	const stateAfter = [
// 		{
// 			id: 0,
// 			text: 'Learn Redux',
// 			completed: false
// 		},
// 		{
// 			id: 1,
// 			text: 'Profit!',
// 			completed: true
// 		}
// 	];
// 	expect(
// 		todos(stateBefore, action)
// 	).toEqual(stateAfter);
// };

// testAddTodo();
// testToggleTodo();

// console.log('All Tests Passed!');
</script>
	</body>
</html>
